package com.market.web.controller.report;

import java.util.ArrayList;
import java.util.List;

import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.market.dao.jpa.report.ReportFactory;
import com.market.domain.Location;
import com.market.domain.Order;
import com.market.domain.Product;
import com.market.domain.transients.ReportHeaderFooter;
import com.market.domain.transients.report.OrderDetailSummaryByProduct;
import com.market.domain.transients.report.SalesGroupByProduct;
import com.market.domain.transients.report.SalesGroupByUser;
import com.market.domain.transients.report.UserRecord;
import com.market.domain.transients.report.WhoBuyIt;
import com.market.manager.OrderManager;
import com.market.web.model.report.ReportModel;

@Component("reportController")
@Scope("session")
public class ReportController {

	@Autowired
	private ReportModel model;
	@Autowired
	private ReportFactory reportFactory;
	@Autowired
	private OrderManager orderManager;

	public ReportModel getModel() {
		return model;
	}

	public void setModel(ReportModel model) {
		this.model = model;
	}
	
	
	public List<WhoBuyIt> loadWhoBuyIt(Product product){
		return this.reportFactory.findWhoBuyIt(product);
	}
	
	public StreamedContent printProduct(List<Product> products){
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Product List");
		this.model.setReportHeaderFooter(hFooter);
		return this.model.printProduct(products);
	}

	/**
	 * This method load sale for a period, eg 2012-01-01->2012-06-3-01
	 */
	public void loadSalesGroupByProduct() {
		List<SalesGroupByProduct> salesGroupByProduct = this.reportFactory
				.findSalesGroupByProduct(this.model
						.getSalesGroupByProductQuery());
		this.model.setSalesGroupByProduct(salesGroupByProduct);
	}

	/**
	 * This method load sale for a period, eg 2012-01-01->2012-06-3-01
	 */
	public void loadSalesGroupByUser() {
		List<SalesGroupByUser> salesGroupByUsers = this.reportFactory
				.findSalesGroupByUser(this.model.getSalesGroupByUserQuery());
		this.model.setSalesGroupByUser(salesGroupByUsers);
	}
	/**
	 * This method load sale for specific date, eg 2012-01-01
	 */
	public void loadOrderDetailSummaryByProduct() {
		List<OrderDetailSummaryByProduct> detailSummary = this.reportFactory
				.findOrderDetailSummaryByProduct(this.model.getOrderQuery());
		this.model.setOrderDetailsSummaryByProducts(detailSummary);
	}

	public StreamedContent getOrderPrepareSummaryPdf() {
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Order Prepare summary report");
		hFooter.setRightHeader("Required Date:"
				+ this.getModel().getOrderQuery().getRequiredDateLabel());
		this.model.setReportHeaderFooter(hFooter);
		return this.model.getOrderPrepareSummaryPdf();
	}
	
	
	public StreamedContent getOrderPurchaseSummaryPdf() {
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Order Purchase summary report");
		hFooter.setRightHeader("Required Date:"
				+ this.getModel().getOrderQuery().getRequiredDateLabel());
		this.model.setReportHeaderFooter(hFooter);
		return this.model.getOrderPurchaseSummaryPdf();
	}

	/**
	 * This method is use from print delivery report and prepare report, In case
	 * network or other problem, We can not prepare orders online. We can use
	 * this printed edition to prepare orders
	 * 
	 * @return Load all locations have orders, and all their orders;
	 */

	public void loadOrdersByLocation() {
		List<Location> ordersByLocation = this.reportFactory
				.findLocationHaveOrder(this.model.getOrderQuery());
		for (Location loc : ordersByLocation) {
			List<Order> orders = new ArrayList<Order>();
			for (Order order : loc.getOrders()) {
				orders.add(orderManager.fetchOne(order));
			}
			loc.setOrders(orders);
		}
		this.model.setOrdersByLocation(ordersByLocation);
	}

	/**
	 * This method use for print a delivery orders list;
	 * 
	 * @return
	 */
	public StreamedContent getOrdersByLocationLocationListPdf() {
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Location (have order) List");
		hFooter.setRightHeader("Required Date:"
				+ this.getModel().getOrderQuery().getRequiredDateLabel());
		this.model.setReportHeaderFooter(hFooter);
		return this.model.getOrdersByLocationLocationListPdf();
	}

	/**
	 * This method use for print a delivery orders list;
	 * 
	 * @return
	 */
	public StreamedContent getOrdersByLocationPdf() {
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Order List");
		hFooter.setRightHeader("Required Date:"
				+ this.getModel().getOrderQuery().getRequiredDateLabel());
		this.model.setReportHeaderFooter(hFooter);
		return this.model.getOrdersByLocationPdf();
	}

	/**
	 * This method use for print a prepare report, orders with detail
	 * 
	 * @return
	 */
	public StreamedContent getOrdersByLocationWithDetailPdf() {
		ReportHeaderFooter hFooter = new ReportHeaderFooter();
		hFooter.setCenterHeader("Order Prepare List");
		hFooter.setRightHeader("Required Date:"
				+ this.getModel().getOrderQuery().getRequiredDateLabel());
		this.model.setReportHeaderFooter(hFooter);
		return this.model.getOrdersByLocationWithDetailPdf();
	}

	/**
	 * This method load user's activity record from database, and set to reportModel;
	 */
	public void loadUserActivityRecords() {
		List<UserRecord> userRecords = this.reportFactory.findUserRecords(this
				.getModel().getUserRecordQuery());
		this.model.setUserRecords(userRecords);
	}
}
